package com.ef.web.action;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.ef.constant.ConfirmMessage;
import com.ef.constant.StatusType;
import com.ef.domain.AdChannel;
import com.ef.domain.MarketingPlan;
import com.ef.domain.PTE;
import com.ef.domain.User;
import com.ef.service.AdChannelService;
import com.ef.service.MarketingPlanService;
import com.ef.service.PTEService;
import com.ef.util.CalendarUtil;
import com.ef.util.CustomExample;
import com.ef.util.PaginationSupport;

public class MarketingPlanAction extends BaseAction<MarketingPlan> {

	private static final long serialVersionUID = 1L;

	protected final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
			.getLog(MarketingPlanAction.class);

	private MarketingPlanService marketingPlanService;

	private AdChannelService adChannelService;

	private PTEService pTEService;

	/**
	 * 选择的年份
	 */
	private int year;
	/**
	 * 选择的月 已处理 从1开始
	 */
	private int month;

	private Date selStartDate;

	private Date selEndDate;

	private List<String> days;

	private Long selAdChannelId;

	private String adChannelName;

	/**
	 * 存在的PTE
	 */
	private List<PTE> optionalPTEList;

	/**
	 * 选到的PTE
	 */
	private List<PTE> selectedPTEList;

	private List<String> selectedpte;

	/**
	 * 选到的PlanId
	 */
	private String selPlanId;

	/**
	 * 选到的天
	 */
	private String selDay;

	private PaginationSupport<AdChannel> adChannels;

	public MarketingPlanAction() {
		Calendar now = Calendar.getInstance();
		month = now.get(Calendar.MONTH) + 1;
		year = now.get(Calendar.YEAR);
	}

	@SuppressWarnings("serial")
	public String list() {
		Calendar selmonth = Calendar.getInstance();
		selmonth.set(Calendar.MONTH, month - 1);
		selmonth.set(Calendar.YEAR, year);
		int day = selmonth.getActualMaximum(Calendar.DAY_OF_MONTH);
		days = new ArrayList<String>(day);
		for (int i = 1; i < day + 1; i++) {
			days.add(String.valueOf(i));
		}
		adChannels = adChannelService.findByExample(
				new CustomExample<AdChannel>(new AdChannel()) {
					public void appendCondition(Criteria criteria) {
						if (adChannelName != null) {
							criteria.add(Restrictions.like("name",
									adChannelName.trim(), MatchMode.ANYWHERE));
							criteria.add(Restrictions.eq("status",
									StatusType.VALID));
						}
						;
						User user = getSessionUser();
						if (user.getRole() != null && user.getRole().isMK()) {
							if (user.getTeam() != null) {
								criteria.add(Restrictions.eq("team", user
										.getTeam()));
							}
						}
						this.enableLike(MatchMode.ANYWHERE);
					}
				}, this.getStartIndex(), this.getPageSize());
		return LIST;
	}

	/**
	 * 获取可以选择的PTE,算法说明: 所以的PTE, 减除已参加PLAN的PTE 修改:可以获取全部的PTE
	 * 
	 * @param fdate
	 *            开始的那天
	 * @param ldate
	 *            结束的那天 TODO 算法优化
	 */
	protected void prepareOptionalPTES(Date fdate, Date ldate) {
		// List<MarketingPlan> plans = marketingPlanService.getPlanBetweenDate(
		// fdate, ldate);
		List<PTE> allPTE = null;
		User user = this.getSessionUser();
		if (user.getRole() != null && user.getRole().isMK()) {
			if (user.getTeam() != null) {
				allPTE = pTEService.findALLVaildByTeam(user.getTeam());
			} else {
				allPTE = pTEService.findALLVaild();
			}
		} else {
			allPTE = pTEService.findALLVaild();
		}

		// for (MarketingPlan plan : plans) {
		// List<PTE> ePTEs = plan.getPtes();
		// if (ePTEs != null && ePTEs.size() > 0) {
		// allPTE.removeAll(ePTEs);
		// }
		// }
		optionalPTEList = allPTE;
	}

	private void fetchListData() {
		MarketingPlan marketingPlan = this.getModel();
		List<PTE> ptes = marketingPlan.getPtes();
		if (ptes != null) {
			selectedPTEList = ptes;
		} else {
			selectedPTEList = new ArrayList<PTE>();
		}
		Date fdate = marketingPlan.getStartDate();
		Date ldate = marketingPlan.getEndDate();
		if (fdate != null && ldate != null) {
			this.prepareOptionalPTES(CalendarUtil.getBeginOfDay(fdate),
					CalendarUtil.getEndOfDay(ldate));
		} else {
			optionalPTEList = new ArrayList<PTE>();
		}
	}

	public String edit() {
		this.selPlanId = "";
		this.selDay = "";
		if (this.selAdChannelId != null) {
			prepareAdChannelMonthPlan();
		}
		entity = new MarketingPlan();
		//fetchListData();
		return EDIT;
	}

	public String select() {
		if (this.selAdChannelId != null) {
			AdChannel adChannel = adChannelService.findById(selAdChannelId);
			adChannelName = adChannel.getName();
			prepareAdChannelMonthPlan();
		}
		if (this.selPlanId != null && selPlanId.trim().length() > 0) {
			this.entity = marketingPlanService
					.findById(Long.valueOf(selPlanId));
			this.id = entity.getId();
		} else if (selDay != null && selDay.trim().length() > 0) {
			entity = new MarketingPlan();
			Calendar date = new GregorianCalendar(year, month - 1, Integer
					.valueOf(selDay));
			entity.setStartDate(date.getTime());
			entity.setEndDate(date.getTime());
		}
		fetchListData();
		return "select";
	}

	public String save() {
		MarketingPlan marketingPlan = this.getModel();
		if (marketingPlan.getStartDate().after(marketingPlan.getEndDate())) {
			this.resultError("ERROR:START mast befor END", "list");
			if (this.selAdChannelId != null) {
				prepareAdChannelMonthPlan();
			}
			fetchListData();
			return EDIT;
		}
		SimpleDateFormat df1 = new SimpleDateFormat("yyyyMM");
		if (!df1.format(marketingPlan.getStartDate()).equals(
				df1.format(marketingPlan.getEndDate()))) {
			this.resultError("ERROR: mast in same month ", "list");
			if (this.selAdChannelId != null) {
				prepareAdChannelMonthPlan();
			}
			fetchListData();
			return EDIT;
		}
		AdChannel adChannel = null;
		if (selAdChannelId != null) {
			adChannel = adChannelService.findById(selAdChannelId);
		}
		List<MarketingPlan> plans = marketingPlanService
				.getAdChannelOtherPlanBetweenDate(CalendarUtil
						.getBeginOfDay(marketingPlan.getStartDate()),
						CalendarUtil.getEndOfDay(marketingPlan.getEndDate()),
						selAdChannelId, marketingPlan.getId());
		if (plans.size() > 0) {
			if (this.selAdChannelId != null) {
				prepareAdChannelMonthPlan();
			}
			fetchListData();
			this.resultError("ERROR:Have plan Error", "list");
			return EDIT;
		}
		marketingPlan.setAdChannel(adChannel);
//		List<PTE> ptes = new ArrayList<PTE>();
//		for (String pteId : selectedpte) {
//			PTE pte = pTEService.findById(Long.valueOf(pteId));
//			ptes.add(pte);
//		}
//		marketingPlan.setPtes(ptes);
		Date sdate = marketingPlan.getStartDate();
		SimpleDateFormat df = new SimpleDateFormat("yyMMdd");
		String f = df.format(sdate);
		marketingPlan.setName(f + "_" + adChannel.getName());
		marketingPlan.setUpdateTime(new Date());
		marketingPlan.setUpdateUser(getSessionUser());
		marketingPlanService.saveOrUpdate(marketingPlan);
		this.setResult(ConfirmMessage.MarketingPlan);
		if (this.selAdChannelId != null) {
			prepareAdChannelMonthPlan();
		}
		fetchListData();
		return EDIT;
	}

	public String delete() {
		marketingPlanService.delete(this.getModel());
		if (this.selAdChannelId != null) {
			prepareAdChannelMonthPlan();
		}
		this.resultOK("delete the plan", "list");
		fetchListData();
		return EDIT;
	}

	private String adChannelMonthPlan;

	protected void prepareAdChannelMonthPlan() {
		// System.out.println("year" + year + "month" + month + "id" + id);
		// 传入的month从1开始
		Date fDay = CalendarUtil.getFirstDayOfMonth(year, month);
		Date lDay = CalendarUtil.getLastDayOfMonth(year, month);
		// 获取 本月计划
		List<MarketingPlan> plans = marketingPlanService
				.getAdChannelPlanBetweenDate(fDay, lDay, selAdChannelId);
		// 生成计划月历
		// 第一天是周几 ,周一是 1
		int fd = CalendarUtil.getDayOfWeek(fDay);
		int dayCount = CalendarUtil.getDayCountOfMonth(year, month);
		StringBuffer responseTable = new StringBuffer();
		int dayOfMonth = 1;
		boolean endOfMonth = false;
		for (int w = 1; w < 43; w++) {
			if (w % 7 == 1) {
				if (endOfMonth) {
					break;
				}
				responseTable.append("<tr>");
			}
			if (w < fd) {
				responseTable
						.append("<td class='tablecolour5' align='center' ></td>");
			} else if (dayOfMonth > dayCount) {
				responseTable
						.append("<td class='tablecolour5' align='center' ></td>");
				endOfMonth = true;
			} else {
				Long planid = hasPlan(dayOfMonth, plans);
				if (planid > 0) {
					String bg = "";
					if (this.selDay != null
							&& selDay.equals(String.valueOf(dayOfMonth))) {
						bg = " bgcolor='green' ";
					}
					responseTable
							.append(
									"<td  align='center' "
											+ bg
											+ " style=\"cursor:pointer\"  ondblclick=\"doSelectPlan('"
											+ dayOfMonth + "','" + planid
											+ "')\" >").append(dayOfMonth)
							.append("</td>");
				} else {
					String bg = "class='tablecolour5' ";
					if (this.selDay != null
							&& selDay.equals(String.valueOf(dayOfMonth))) {
						bg = " bgcolor='green' ";
					}
					responseTable
							.append("<td   "
									+ bg
									+ " style=\"cursor:pointer\"  ondblclick=\"doSelectDay('"
									+ dayOfMonth + "')\" align='center' >"
									+ dayOfMonth + "</td>");
				}
				dayOfMonth++;
			}
			if (w % 7 == 0) {
				responseTable.append("</tr>");
			}
		}
		adChannelMonthPlan = responseTable.toString();
		// System.out.println(adChannelMonthPlan);
	};

	// TODO 中文过滤
	public String autoCompleteAjax() {
		HttpServletResponse response = ServletActionContext.getResponse();
		HttpServletRequest request = ServletActionContext.getRequest();
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/plain;charset=GBK ");
		PrintWriter out = null;
		try {
			String q = request.getParameter("q");
			String limit = request.getParameter("limit");
			List<MarketingPlan> list = marketingPlanService.findByAnything(q,
					Integer.valueOf(limit));
			// {id:id,name:name}
			String responseStr = "";
			// System.out.println(q);
			out = response.getWriter();
			for (MarketingPlan key : list) {
				String aid = "";
				String aname = "";
				String pid = "";
				String pname = "";
				if (key.getAdChannel() != null) {
					aid = key.getAdChannel().getId().toString();
					aname = key.getAdChannel().getName();
					if (key.getAdChannel().getMarketingPolicy() != null) {
						pid = key.getAdChannel().getMarketingPolicy().getId()
								.toString();
						pname = key.getAdChannel().getMarketingPolicy()
								.getName();
					}
				}
				responseStr = ("{id:") + (key.getId()) + (",name:\"")
						+ (key.getName()) + ("\",aid:\"") + aid
						+ ("\",aname:\"") + aname + ("\",pid:\"") + pid
						+ ("\",pname:\"") + pname + ("\"}");
				// System.out.println(responseStr);
				out.println(responseStr);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {

				}
			}
		}
		return null;
	}

	/**
	 * 判断某天是否有活动.<br/>
	 * 前提.1.开始时间结束时间都有。2.不能跨月。
	 * 
	 * @param dayOfMonth
	 * @param plans
	 * @return
	 */
	protected Long hasPlan(int dayOfMonth, List<MarketingPlan> plans) {
		int sDofMonth = 0;
		int eDofMonth = 0;
		for (MarketingPlan plan : plans) {
			if (plan.getStartDate() != null) {
				sDofMonth = CalendarUtil.getDayOfMonth(plan.getStartDate());
			}
			if (dayOfMonth < sDofMonth) {
				return 0l;
			}
			if (dayOfMonth == sDofMonth) {
				return plan.getId();
			}
			if (plan.getEndDate() != null) {
				eDofMonth = CalendarUtil.getDayOfMonth(plan.getEndDate());
			}
			if (dayOfMonth <= eDofMonth) {
				return plan.getId();
			}
		}
		return 0l;
	}

	private Long cacheAdChannelId = 0l;

	private List<MarketingPlan> cachePlans = null;

	public Long getAdChannelPlan(int year, int month, String day,
			String channelId) {
		Long cId = Long.valueOf(channelId);
		if (!cacheAdChannelId.equals(cId)) {
			Date fDay = CalendarUtil.getFirstDayOfMonth(year, month);
			Date lDay = CalendarUtil.getLastDayOfMonth(year, month);
			// 获取 本月计划
			cachePlans = marketingPlanService.getAdChannelPlanBetweenDate(fDay,
					lDay, cId);
			cacheAdChannelId = cId;
		}
		for (MarketingPlan plan : cachePlans) {
			int fd = CalendarUtil.getDayOfMonth(plan.getStartDate());
			int ld = CalendarUtil.getDayOfMonth(plan.getEndDate());
			int d = Integer.valueOf(day);
			if ((fd <= d) && (d <= ld)) {
				return plan.getId();
			}
		}
		return -1l;
	}
	

	// TODO 中文过滤
	public String autoCompleteAjaxWithTeam() {
		HttpServletResponse response = ServletActionContext.getResponse();
		HttpServletRequest request = ServletActionContext.getRequest();
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/plain;charset=GBK ");
		PrintWriter out = null;
		try {
			String q = request.getParameter("q");
			String limit = request.getParameter("limit");
			List<MarketingPlan> list = null;
			if (this.getSessionUser() != null
					&& this.getSessionUser().getTeam() != null) {
				list = marketingPlanService.findByAnythingByTeamId(q, Integer
						.valueOf(limit), this.getSessionUser().getTeam()
						.getId());
			} else {
				list = marketingPlanService.findByAnything(q, Integer
						.valueOf(limit));
			}
			// {id:id,name:name}
			String responseStr = "";
			// System.out.println(q);
			out = response.getWriter();
			for (MarketingPlan key : list) {
				String aid = "";
				String aname = "";
				String pid = "";
				String pname = "";
				if (key.getAdChannel() != null) {
					aid = key.getAdChannel().getId().toString();
					aname = key.getAdChannel().getName();
					if (key.getAdChannel().getMarketingPolicy() != null) {
						pid = key.getAdChannel().getMarketingPolicy().getId()
								.toString();
						pname = key.getAdChannel().getMarketingPolicy()
								.getName();
					}
				}
				responseStr = ("{id:") + (key.getId()) + (",name:\"")
						+ (key.getName()) + ("\",aid:\"") + aid
						+ ("\",aname:\"") + aname + ("\",pid:\"") + pid
						+ ("\",pname:\"") + pname + ("\"}");
				// System.out.println(responseStr);
				out.println(responseStr);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {

				}
			}
		}
		return null;
	}


	public MarketingPlanService getMarketingPlanService() {
		return marketingPlanService;
	}

	public void setMarketingPlanService(
			MarketingPlanService marketingPlanService) {
		this.marketingPlanService = marketingPlanService;
	}

	public AdChannelService getAdChannelService() {
		return adChannelService;
	}

	public void setAdChannelService(AdChannelService adChannelService) {
		this.adChannelService = adChannelService;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public List<String> getDays() {
		return days;
	}

	public void setDays(List<String> days) {
		this.days = days;
	}

	public PaginationSupport<AdChannel> getAdChannels() {
		return adChannels;
	}

	public void setAdChannels(PaginationSupport<AdChannel> adChannels) {
		this.adChannels = adChannels;
	}

	public String getAdChannelName() {
		return adChannelName;
	}

	public void setAdChannelName(String adChannelName) {
		this.adChannelName = adChannelName;
	}

	public Date getSelStartDate() {
		return selStartDate;
	}

	public void setSelStartDate(Date selStartDate) {
		this.selStartDate = selStartDate;
	}

	public Date getSelEndDate() {
		return selEndDate;
	}

	public void setSelEndDate(Date selEndDate) {
		this.selEndDate = selEndDate;
	}

	public Long getSelAdChannelId() {
		return selAdChannelId;
	}

	public void setSelAdChannelId(Long selAdChannelId) {
		this.selAdChannelId = selAdChannelId;
	}

	public String getAdChannelMonthPlan() {
		return adChannelMonthPlan;
	}

	public void setAdChannelMonthPlan(String adChannelMonthPlan) {
		this.adChannelMonthPlan = adChannelMonthPlan;
	}

	public String getSelPlanId() {
		return selPlanId;
	}

	public void setSelPlanId(String selPlanId) {
		this.selPlanId = selPlanId;
	}

	public String getSelDay() {
		return selDay;
	}

	public void setSelDay(String selDay) {
		this.selDay = selDay;
	}

	/**
	 * 小心名字
	 * 
	 * @return
	 */
	public PTEService getpTEService() {
		return pTEService;
	}

	public void setpTEService(PTEService pTEService) {
		this.pTEService = pTEService;
	}

	public List<PTE> getOptionalPTEList() {
		return optionalPTEList;
	}

	public void setOptionalPTEList(List<PTE> optionalPTEList) {
		this.optionalPTEList = optionalPTEList;
	}

	public List<PTE> getSelectedPTEList() {
		return selectedPTEList;
	}

	public void setSelectedPTEList(List<PTE> selectedPTEList) {
		this.selectedPTEList = selectedPTEList;
	}

	public List<String> getSelectedpte() {
		return selectedpte;
	}

	public void setSelectedpte(List<String> selectedpte) {
		this.selectedpte = selectedpte;
	}

	public PTEService getPTEService() {
		return pTEService;
	}

	public void setPTEService(PTEService service) {
		pTEService = service;
	}
}
